From d738d8d58d4de1f96c16a892e1e343edb58847b9 Mon Sep 17 00:00:00 2001 From: Sven Neumann Date: Thu, 10 Jan 2008 21:48:19 +0000 Subject: [PATCH] added extension to speed up code paths that are executed by the GIMP/GEGL 2008-01-10 Sven Neumann * extensions/gimp-8bit.c: added extension to speed up code paths that are executed by the GIMP/GEGL hybrid. So far only 8bit to float conversions are handled. svn path=/trunk/; revision=273 --- ChangeLog | 6 + extensions/gimp-8bit.c | 405 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 411 insertions(+) create mode 100644 extensions/gimp-8bit.c diff --git a/ChangeLog b/ChangeLog index dd73549..9731e30 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2008-01-10 Sven Neumann + + * extensions/gimp-8bit.c: added extension to speed up code paths + that are executed by the GIMP/GEGL hybrid. So far only 8bit to + float conversions are handled. + 2008-01-10 Sven Neumann * extensions/Makefile.am: extended CFLAGS so that config.h can be diff --git a/extensions/gimp-8bit.c b/extensions/gimp-8bit.c new file mode 100644 index 0000000..ec187b4 --- /dev/null +++ b/extensions/gimp-8bit.c @@ -0,0 +1,405 @@ +/* babl - dynamically extendable universal pixel conversion library. + * Copyright (C) 2005, Øyvind Kolås. + * + * Optimized 8bit conversion routines as used by legacy GIMP code. + * Copyright (C) 2008 Sven Neumann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, see + * . + */ + +#include "config.h" + +#include + +#include "babl.h" + +#include "base/util.h" + +#define INLINE inline + + +/* lookup tables used in conversion */ + +static float lut_linear[1 << 8]; +static float lut_gamma_2_2[1 << 8]; + + +static void +tables_init (void) +{ + int i; + + /* fill tables for conversion from 8 bit integer to float */ + for (i = 0; i < 1 << 8; i++) + { + double value = i / 255.0; + + lut_linear[i] = value; + lut_gamma_2_2[i] = gamma_2_2_to_linear (value); + } +} + +static INLINE long +u8_linear_to_float_linear (unsigned char *src, + unsigned char *dst, + long samples) +{ + float *d = (float *) dst; + long n = samples; + + while (n--) + *d++ = lut_linear[*src++]; + + return samples; +} + +static INLINE long +u8_gamma_2_2_to_float_linear (unsigned char *src, + unsigned char *dst, + long samples) +{ + float *d = (float *) dst; + long n = samples; + + while (n--) + *d++ = lut_linear[*src++]; + + return samples; +} + +static INLINE long +conv_rgba8_linear_rgbaF_linear (unsigned char *src, + unsigned char *dst, + long samples) +{ + u8_linear_to_float_linear (src, dst, samples * 4); + + return samples; +} + +static INLINE long +conv_rgba8_gamma_2_2_rgbaF_linear (unsigned char *src, + unsigned char *dst, + long samples) +{ + float *d = (float *) dst; + long n = samples; + + while (n--) + { + *d++ = lut_gamma_2_2[*src++]; + *d++ = lut_gamma_2_2[*src++]; + *d++ = lut_gamma_2_2[*src++]; + *d++ = lut_linear[*src++]; + } + + return samples; +} + +static INLINE long +conv_rgb8_linear_rgbF_linear (unsigned char *src, + unsigned char *dst, + long samples) +{ + u8_linear_to_float_linear (src, dst, samples * 3); + + return samples; +} + +static INLINE long +conv_rgb8_gamma_2_2_rgbF_linear (unsigned char *src, + unsigned char *dst, + long samples) +{ + u8_gamma_2_2_to_float_linear (src, dst, samples * 3); + + return samples; +} + +static INLINE long +conv_rgb8_linear_rgbaF_linear (unsigned char *src, + unsigned char *dst, + long samples) +{ + float *d = (float *) dst; + long n = samples; + + while (n--) + { + *d++ = lut_linear[*src++]; + *d++ = lut_linear[*src++]; + *d++ = lut_linear[*src++]; + *d++ = 1.0; + } + + return samples; +} + +static INLINE long +conv_rgb8_gamma_2_2_rgbaF_linear (unsigned char *src, + unsigned char *dst, + long samples) +{ + float *d = (float *) dst; + long n = samples; + + while (n--) + { + *d++ = lut_gamma_2_2[*src++]; + *d++ = lut_gamma_2_2[*src++]; + *d++ = lut_gamma_2_2[*src++]; + *d++ = 1.0; + } + + return samples; +} + +static INLINE long +conv_ga8_linear_gaF_linear (unsigned char *src, + unsigned char *dst, + long samples) +{ + u8_linear_to_float_linear (src, dst, samples * 2); + + return samples; +} + +static INLINE long +conv_ga8_gamma_2_2_gaF_linear (unsigned char *src, + unsigned char *dst, + long samples) +{ + float *d = (float *) dst; + long n = samples; + + while (n--) + { + *d++ = lut_gamma_2_2[*src++]; + *d++ = lut_linear[*src++]; + } + + return samples; +} + +static INLINE long +conv_ga8_linear_rgbaF_linear (unsigned char *src, + unsigned char *dst, + long samples) +{ + float *d = (float *) dst; + long n = samples; + + while (n--) + { + float value = lut_linear[*src++]; + + *d++ = value; + *d++ = value; + *d++ = value; + *d++ = lut_linear[*src++]; + } + + return samples; +} + +static INLINE long +conv_ga8_gamma_2_2_rgbaF_linear (unsigned char *src, + unsigned char *dst, + long samples) +{ + float *d = (float *) dst; + long n = samples; + + while (n--) + { + float value = lut_gamma_2_2[*src++]; + + *d++ = value; + *d++ = value; + *d++ = value; + *d++ = lut_linear[*src++]; + } + + return samples; +} + +static INLINE long +conv_g8_linear_gF_linear (unsigned char *src, + unsigned char *dst, + long samples) +{ + u8_linear_to_float_linear (src, dst, samples); + + return samples; +} + +static INLINE long +conv_g8_gamma_2_2_gF_linear (unsigned char *src, + unsigned char *dst, + long samples) +{ + u8_gamma_2_2_to_float_linear (src, dst, samples); + + return samples; +} + +static INLINE long +conv_g8_linear_rgbaF_linear (unsigned char *src, + unsigned char *dst, + long samples) +{ + float *d = (float *) dst; + long n = samples; + + while (n--) + { + float value = lut_linear[*src++]; + + *d++ = value; + *d++ = value; + *d++ = value; + *d++ = 1.0; + } + + return samples; +} +static INLINE long +conv_g8_gamma_2_2_rgbaF_linear (unsigned char *src, + unsigned char *dst, + long samples) +{ + float *d = (float *) dst; + long n = samples; + + while (n--) + { + float value = lut_gamma_2_2[*src++]; + + *d++ = value; + *d++ = value; + *d++ = value; + *d++ = 1.0; + } + + return samples; +} + + +int +init (void) +{ + Babl *rgbaF_linear = babl_format_new ( + babl_model ("RGBA"), + babl_type ("float"), + babl_component ("R"), + babl_component ("G"), + babl_component ("B"), + babl_component ("A"), + NULL); + Babl *rgba8_linear = babl_format_new ( + babl_model ("RGBA"), + babl_type ("u8"), + babl_component ("R"), + babl_component ("G"), + babl_component ("B"), + babl_component ("A"), + NULL); + Babl *rgba8_gamma_2_2 = babl_format_new ( + babl_model ("R'G'B'A"), + babl_type ("u8"), + babl_component ("R'"), + babl_component ("G'"), + babl_component ("B'"), + babl_component ("A"), + NULL); + Babl *rgbF_linear = babl_format_new ( + babl_model ("RGB"), + babl_type ("float"), + babl_component ("R"), + babl_component ("G"), + babl_component ("B"), + NULL); + Babl *rgb8_linear = babl_format_new ( + babl_model ("RGB"), + babl_type ("u8"), + babl_component ("R"), + babl_component ("G"), + babl_component ("B"), + NULL); + Babl *rgb8_gamma_2_2 = babl_format_new ( + babl_model ("R'G'B'"), + babl_type ("u8"), + babl_component ("R'"), + babl_component ("G'"), + babl_component ("B'"), + NULL); + Babl *gaF_linear = babl_format_new ( + babl_model ("YA"), + babl_type ("float"), + babl_component ("Y"), + babl_component ("A"), + NULL); + Babl *ga8_linear = babl_format_new ( + babl_model ("YA"), + babl_type ("u8"), + babl_component ("Y"), + babl_component ("A"), + NULL); + Babl *ga8_gamma_2_2 = babl_format_new ( + babl_model ("Y'A"), + babl_type ("u8"), + babl_component ("Y'"), + babl_component ("A"), + NULL); + Babl *gF_linear = babl_format_new ( + babl_model ("Y"), + babl_type ("float"), + babl_component ("Y"), + NULL); + Babl *g8_linear = babl_format_new ( + babl_model ("Y"), + babl_type ("u8"), + babl_component ("Y"), + NULL); + Babl *g8_gamma_2_2 = babl_format_new ( + babl_model ("Y'"), + babl_type ("u8"), + babl_component ("Y'"), + NULL); + + tables_init (); + +#define o(src, dst) \ + babl_conversion_new (src, dst, "linear", conv_ ## src ## _ ## dst, NULL) + + o (rgba8_linear, rgbaF_linear); + o (rgba8_gamma_2_2, rgbaF_linear); + + o (rgb8_linear, rgbF_linear); + o (rgb8_gamma_2_2, rgbF_linear); + o (rgb8_linear, rgbaF_linear); + o (rgb8_gamma_2_2, rgbaF_linear); + + o (ga8_linear, gaF_linear); + o (ga8_gamma_2_2, gaF_linear); + o (ga8_linear, rgbaF_linear); + o (ga8_gamma_2_2, rgbaF_linear); + + o (g8_linear, gF_linear); + o (g8_gamma_2_2, gF_linear); + o (g8_linear, rgbaF_linear); + o (g8_gamma_2_2, rgbaF_linear); + return 0; +} -- 2.30.2